package zack.project.domain.activity.service.discount;

import zack.project.domain.activity.adapter.repository.IActivityRepository;
import zack.project.domain.activity.model.valobj.DiscountTypeEnum;
import zack.project.domain.activity.model.valobj.GroupBuyActivityDiscountVO;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.math.BigDecimal;

/**
 * @author zack.project
 * @description 折扣计算服务抽象类
 * @create 2024-12-22 12:32
 */
@Slf4j
public abstract class AbstractDiscountCalculateService implements IDiscountCalculateService {

    @Resource
    protected IActivityRepository repository;

    /**
     * 在进行优惠试算之前，要根据该活动配置的折扣，
     * 看该折扣是否开启人群过滤(对应数据库表{group_buy_discount}下的discount_type字段)
     * @param userId           用户ID
     * @param originalPrice    商品原始价格
     * @param groupBuyDiscount 折扣计划配置
     * @return
     */
    @Override
    public BigDecimal calculate(String userId,
                                BigDecimal originalPrice,
                                GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount) {
        // 1. 人群标签过滤
        //tagId在redis有对应的entry(key:tagId,value:位图)，
        // 对用户id进行一系列哈希，在该tagId对应的位图中看该哈希对应索引下的值是否是1
        //优惠的人群过滤规则:只有该tagId下的人群可以使用该优惠
        if (DiscountTypeEnum.TAG.equals(groupBuyDiscount.getDiscountType())){
            boolean isCrowdRange = filterTagId(userId, groupBuyDiscount.getTagId());
            if (!isCrowdRange) {
                log.info("折扣优惠计算拦截，用户不再优惠人群标签范围内 userId:{}", userId);
                return originalPrice;
            }
        }
        // 2. 折扣优惠计算
        return doCalculate(originalPrice, groupBuyDiscount);
    }

    // 人群过滤 - 限定人群优惠
    private boolean filterTagId(String userId, String tagId) {
        return repository.isTagCrowdRange(tagId, userId);
    }

    protected abstract BigDecimal doCalculate(BigDecimal originalPrice, GroupBuyActivityDiscountVO.GroupBuyDiscount groupBuyDiscount);

}
